
from langchain_community.llms.tongyi import Tongyi
import os
os.environ["DASHSCOPE_API_KEY"] = "sk-9d8f1914800e497f8717144e860f99bc"

# 创建语言模型
llm = Tongyi()

# 构建工具
from langchain.agents import tool

@tool
def get_word_length(word: str) -> int:
    """返回单词的长度"""
    return len(word)


# 创建工具清单
tools = [get_word_length]

# 绑定工具
from langchain.tools.render import format_tool_to_openai_function  # 格式化函数作为符合openai格式的描述体

llm_with_tools = llm.bind(
    functions=[format_tool_to_openai_function(t) for t in tools]
)
#  创建代理
from langchain.agents.format_scratchpad import format_to_openai_functions
from langchain.agents.output_parsers import OpenAIFunctionsAgentOutputParser
from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个非常优秀的人，但是不会计算单词的长度"),
    ("user", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad"),  # 消息体当中添加一个 key，记录代理的使用过程
])

agent = {
            "input": lambda x: x["input"],
            "agent_scratchpad": lambda x: format_to_openai_functions(x['intermediate_steps'])  # 代理的使用过程
        } | prompt | llm_with_tools | OpenAIFunctionsAgentOutputParser()

from langchain.schema.agent import AgentFinish

intermediate_steps = []
count = 1
while True:

    output = agent.invoke({
        "input": "关于color有多少个字母?",
        "intermediate_steps": intermediate_steps
    })
    print(f'\n轮询第{count}次', output, '过程对象：', type(output))
    count += 1

    # 判断代理是否有结束标记，有的话结束
    if isinstance(output, AgentFinish):
        final_result = output.return_values["output"]
        break
    else:
        # 从AgentAction 中提取要执行的 tool（工具名称），跟tool_input（工具的输入参数）
        tool = {
            "get_word_length": get_word_length
        }[output.tool]
        observation = tool.run(output.tool_input)  # 运行工具函数，并且得到结果
        intermediate_steps.append((output, observation))

